package sybel.pan;

import javax.swing.JOptionPane;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import sybel.DOMPanelInterface;
import sybel.DomBuilder;

/**
 *
 * @author Stefano
 */
public class TabBehaviour extends javax.swing.JPanel implements DOMPanelInterface{

    /** Creates new form TabBehaviour */
    @SuppressWarnings("OverridableMethodCallInConstructor")
    public TabBehaviour(Node behaviourNode) {
        count = 0;
        behaviour = (Element)behaviourNode;
        doc = behaviour.getOwnerDocument();
        initComponents(); // init componenti grafici
        setBehaviourAttributes(behaviour); // init dagli attributi del tag <behaviour>
        setInterSystemActor(); // init di system ed Interactive Actor
        initPanel(); // init lista <attributes>
    }


    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jLabelID = new javax.swing.JLabel();
        jLabel1 = new javax.swing.JLabel();
        jLabelDomain = new javax.swing.JLabel();
        jTextName = new javax.swing.JTextField();
        jTextID = new javax.swing.JTextField();
        jTextDomain = new javax.swing.JTextField();
        jPanel1 = new javax.swing.JPanel();
        jLabel2 = new javax.swing.JLabel();
        jLabel3 = new javax.swing.JLabel();
        jScrollPane1 = new javax.swing.JScrollPane();
        jPanel8 = new javax.swing.JPanel();
        jPanelAttr = new javax.swing.JPanel();
        jSeparator1 = new javax.swing.JSeparator();
        jLabel4 = new javax.swing.JLabel();
        jLabel5 = new javax.swing.JLabel();
        jCBInteractActor = new javax.swing.JComboBox();
        jCBSystemActor = new javax.swing.JComboBox();

        jLabelID.setText("ID:");

        jLabel1.setText("*Name:");

        jLabelDomain.setText("*Domain:");

        jTextName.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(204, 0, 0), 2));

        jTextDomain.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(204, 0, 0), 2));

        jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Attributes"));

        jLabel2.setText("Name");

        jLabel3.setText("Value");

        jScrollPane1.setBorder(null);

        jPanelAttr.setLayout(new javax.swing.BoxLayout(jPanelAttr, javax.swing.BoxLayout.Y_AXIS));

        javax.swing.GroupLayout jPanel8Layout = new javax.swing.GroupLayout(jPanel8);
        jPanel8.setLayout(jPanel8Layout);
        jPanel8Layout.setHorizontalGroup(
            jPanel8Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jPanelAttr, javax.swing.GroupLayout.DEFAULT_SIZE, 579, Short.MAX_VALUE)
        );
        jPanel8Layout.setVerticalGroup(
            jPanel8Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel8Layout.createSequentialGroup()
                .addComponent(jPanelAttr, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(161, Short.MAX_VALUE))
        );

        jScrollPane1.setViewportView(jPanel8);

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 579, Short.MAX_VALUE)
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, 52, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(161, 161, 161)
                        .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, 52, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addContainerGap())
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel2)
                    .addComponent(jLabel3))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 161, Short.MAX_VALUE)
                .addContainerGap())
        );

        jLabel4.setText("Interactive Actor:");

        jLabel5.setText("System Actor:");

        jCBInteractActor.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "default" }));

        jCBSystemActor.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "default" }));

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                            .addComponent(jLabel1)
                            .addComponent(jLabelID))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jTextID, javax.swing.GroupLayout.DEFAULT_SIZE, 276, Short.MAX_VALUE)
                            .addComponent(jTextName, javax.swing.GroupLayout.DEFAULT_SIZE, 276, Short.MAX_VALUE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jLabelDomain)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jTextDomain, javax.swing.GroupLayout.PREFERRED_SIZE, 173, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(58, 58, 58))
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jSeparator1, javax.swing.GroupLayout.DEFAULT_SIZE, 591, Short.MAX_VALUE)
                        .addContainerGap())
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, 97, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jCBInteractActor, javax.swing.GroupLayout.PREFERRED_SIZE, 98, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(50, 50, 50)
                        .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, 82, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jCBSystemActor, javax.swing.GroupLayout.PREFERRED_SIZE, 98, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addContainerGap())))
            .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(jTextName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(jTextDomain, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(jLabelDomain))
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jLabel1)
                        .addGap(27, 27, 27)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jLabelID)
                            .addComponent(jTextID, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel4)
                    .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, 17, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jCBSystemActor, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jCBInteractActor, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(18, 18, 18)
                .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
    }// </editor-fold>//GEN-END:initComponents
/**
 * Questo metodo aggiunge ed inizializza i campi degli attributi
 */
    public void initPanel() {
        Node attributes = doc.getElementsByTagName("attributes").item(0);
        NodeList attributeChilds = attributes.getChildNodes();
        if(attributeChilds.getLength() != 0)
            // per ogni nodo figlio di attributes aggiunge un pannello Attribute
            // contenente nome dell'attributo e valore
            for(int i=0; i < attributeChilds.getLength(); i++){
                Element el = (Element)attributeChilds.item(i);
                newLineOfAttributes(el.getTagName(),el.getTextContent());
            }
        else
            newLineOfAttributes(5);
    }

/**
 * Restituisce l'interactive Actor selezionato sotto forma di stringa o null se si
 * tratta di quello di default
 *
 * @return
 */
    public String getSelectedInterActor(){
        if(jCBInteractActor.getSelectedIndex() != 0)
            return jCBInteractActor.getSelectedItem().toString();
        return null;
    }

 /**
 * Restituisce il System Actor selezionato sotto forma di stringa o null se si
 * tratta di quello di default
 *
 * @return
 */
    public String getSelectedSystemActor(){
        if(jCBSystemActor.getSelectedIndex() != 0)
            return jCBSystemActor.getSelectedItem().toString();
        return null;
    }

    /**
     * Salvataggio degli attributi del nodo behaviour e dei nodi di attributes
     * @return nodo behaviour
     */
    public Node saveData(){
        // se c'è un errore in qualche campo il metodo si interrompe
        if(!checkFields())
            return null;

        behaviour.setAttribute("name",jTextName.getText());
        behaviour.setAttribute("domain",jTextDomain.getText());
        if(jTextID.getText().isEmpty())
            behaviour.removeAttribute("id");
        else
            behaviour.setAttribute("id",jTextID.getText());

   //-----------------Interactive e System Actor -------------------------------------//

        String interAct = getSelectedInterActor();
        String systemAct = getSelectedSystemActor();
        /* se l'interactive actor selezionato non è quello di default; se nel DOM
         *  non è ancora specificato si crea il nodo interactiveActor altrimenti
         * si aggiorna il suo valore
         */
        if(interAct != null){
            if(!DomBuilder.hasInteractiveActor(doc)){
                Element interElem = doc.createElement("interactiveActor");
                interElem.setTextContent(interAct);
                Node ref = behaviour.getFirstChild().getNextSibling();
                if(ref.getNodeName() != "parameters")
                    behaviour.insertBefore(interElem, ref);
                else
                    behaviour.insertBefore(interElem, ref.getNextSibling());
            }else{
                behaviour.getElementsByTagName("interactiveActor").item(0).setTextContent(interAct);
            }
        }

        /* come sopra ma per il system actor
         */
        if(systemAct != null){
            if(!DomBuilder.hasInteractiveActor(doc)){
                Element interElem = doc.createElement("systemActor");
                interElem.setTextContent(systemAct);
                Node ref = behaviour.getFirstChild().getNextSibling();
                if(ref.getNodeName() != "parameters")
                    if(ref.getNextSibling().getNodeName() != "interactiveActor")
                        behaviour.insertBefore(interElem, ref.getNextSibling());
                else
                    behaviour.insertBefore(interElem, ref.getNextSibling().getNextSibling());
            }else{
                behaviour.getElementsByTagName("interactiveActor").item(0).setTextContent(systemAct);
            }
        }

     // -------------- Attributes -----------------------------------------//
        Element attributes = doc.createElement("attributes");
        for(int i=0; i<jPanelAttr.getComponentCount();i++){
            Attribute a = (Attribute)jPanelAttr.getComponent(i);
            if(!a.isEmpty()){
                Element attr = doc.createElement(a.getName());
                attr.setTextContent(a.getValue());
                attributes.appendChild(attr);
            }
         }
        // ora si sostituisce il nuovo nodo "attributes" con il vecchio
        behaviour.replaceChild(attributes, behaviour.getFirstChild());
        return (Node)behaviour;
    }

    public void setbehName(String name){
        jTextName.setText(name);
    }

    public void setbehDomain(String domain){
        jTextDomain.setText(domain);
    }

    public void setbehID(String id){
        jTextID.setText(id);
    }

    /**
     * Metodo che legge gli attributi del tag "behaviour" come nome,dominio e id
     * e compila i rispettivi campi
     *
     * @param n nodo radice del behaviour
     */
    public void setBehaviourAttributes(Node n){
        Element el = (Element)n;
        setbehName(el.getAttribute("name"));
        setbehDomain(el.getAttribute("domain"));
        setbehID(el.getAttribute("id"));
    }

    /**
     * Metodo per settare sull'interfaccia l'interactive ed il system actor
     */
    public void setInterSystemActor(){
        String interAct = DomBuilder.getInteractiveActor(doc) ;
        String systemAct = DomBuilder.getSystemActor(doc);

        if(interAct == null)
            jCBInteractActor.setSelectedIndex(0);
        else
            jCBInteractActor.setSelectedItem(interAct);

        if(systemAct == null)
            jCBSystemActor.setSelectedIndex(0);
        else
            jCBSystemActor.setSelectedItem(systemAct);

    }

    public void newLineOfAttributes(String name, String value){
        Attribute attr;
        if((name != null)&&(value!=null))
            attr = new Attribute(this,name,value);
        else
            attr = new Attribute(this);
        if(count > 0){
            // tolgo il pulsante + dagli attributo precedente a quello appena inserito
            ((Attribute)jPanelAttr.getComponent(count-1)).togglePlusButton(false);
        }

        jPanelAttr.add(attr);
        count++;
    }

     public void newLineOfAttributes(int n){
        for (int i=0; i<n ; i++){
            Attribute attr = new Attribute(this);
            if(count > 0){
                // tolgo il pulsante + dagli attributo precedente a quello appena inserito
                ((Attribute)jPanelAttr.getComponent(count-1)).togglePlusButton(false);
            }
                
            jPanelAttr.add(attr);
            count++;
        }
     }

     public int AttributesCount(){
         return jPanelAttr.getComponentCount();
     }


     public void deleteAttribute(Attribute obj){
         count--;
         int a = jPanelAttr.getComponentCount();
         if(jPanelAttr.getComponent(a-1)== obj)
             ((Attribute)jPanelAttr.getComponent(count-1)).togglePlusButton(true);
         jPanelAttr.remove(obj);
     }

     /**
      * Metodo che controlla la corretta immissione dei dati e restituisce false
      * se ci sono errori o true se i dati sono stati immessi correttamente
      * @return true se i campi sono tutti correttamente compilati
      * @return false se c'è un errore di compilazione nei campi
      */
     private boolean checkFields() {
         // controllo dei valori name e domain
         if(jTextName.getText().isEmpty() || jTextDomain.getText().isEmpty()){
            JOptionPane.showMessageDialog(null, "The marked fields are required");
            return false;
         }
         // controllo degli attributi
         for(int i=0; i<jPanelAttr.getComponentCount();i++){
             if(!((Attribute)jPanelAttr.getComponent(i)).checkfield())
                 return false;
         }
         return true;
     }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JComboBox jCBInteractActor;
    private javax.swing.JComboBox jCBSystemActor;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabelDomain;
    private javax.swing.JLabel jLabelID;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel8;
    private javax.swing.JPanel jPanelAttr;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JSeparator jSeparator1;
    private javax.swing.JTextField jTextDomain;
    private javax.swing.JTextField jTextID;
    private javax.swing.JTextField jTextName;
    // End of variables declaration//GEN-END:variables
    private int count; // numero di pannelli Attribute allocati
    private Element behaviour;
    private Document doc;

}
